<?php

class myUser extends sfBasicSecurityUser
{
    protected
    $user = null,
    $doctor = null,
    $admin = null,
    $member = null,
    $isSuperAdmin = false;

    /**
     * Initializes the dpSecurityUser object.
     *
     * @param sfEventDispatcher $dispatcher The event dispatcher object
     * @param sfStorage $storage The session storage object
     * @param array $options An array of options
     */
    public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
    {
        parent::initialize($dispatcher, $storage, $options);

        if (!$this->isAuthenticated())
        {
            // remove user if timeout
            $this->getAttributeHolder()->removeNamespace('dpSecurityUser');
            $this->user = null;
        }
        elseif ($user = $this->getUser())
        {
            $this->isSuperAdmin = $user->get('is_super_admin');
        }
    }

    /**
     * Sets authentication for user.
     *
     * @param  bool $authenticated
     */
    public function setAuthenticated($authenticated)
    {
        parent::setAuthenticated($authenticated);

        if ($this->isAuthenticated() && ($user = $this->getUser()))
        {
            $this->isSuperAdmin = $user->get('is_super_admin');
        }
        else
        {
            $this->isSuperAdmin = false;
            $this->user = null;
        }
    }

    /**
     * Returns the referer uri.
     *
     * @param string $default The default uri to return
     * @return string $referer The referer
     */
    public function getReferer($default)
    {
        $referer = $this->getAttribute('referer', $default);
        $this->getAttributeHolder()->remove('referer');

        return $referer;
    }

    /**
     * Sets the referer.
     *
     * @param string $referer
     */
    public function setReferer($referer)
    {
        if (!$this->hasAttribute('referer'))
        {
            $this->setAttribute('referer', $referer);
        }
    }

    /**
     * Returns whether or not the user can do that
     *
     * @param string $credential The credential name
     * @return boolean
     */
    public function can($credentials)
    {
        if (empty($credentials))
        {
            return true;
        }
        elseif (!$this->isAuthenticated())
        {
            return false;
        }
        elseif ($this->isSuperAdmin)
        {
            return true;
        }

        if (is_string($credentials))
        {
            $credentials = array_map('trim', explode(',', $credentials));
        }

        if (is_array($credentials))
        {
            return (bool) count(array_intersect($credentials, $this->credentials));
        }

        throw new sfException('Bad credentials : ' . $credentials);
    }

    /**
     * Returns whether or not the user has the given credential.
     *
     * @param string $credential The credential name
     * @param boolean $useAnd Whether or not to use an AND condition
     * @return boolean
     */
    public function hasCredential($credential, $useAnd = true)
    {
        if (empty($credential))
        {
            return true;
        }

        if ($this->isSuperAdmin)
        {
            return true;
        }

        return parent::hasCredential($credential, $useAnd);
    }

    /**
     * Returns whether or not the user is a super admin.
     *
     * @return boolean
     */
    public function isSuperAdmin()
    {
        return $this->isSuperAdmin;
    }

    /**
     * Returns whether or not the user is anonymous.
     *
     * @return boolean
     */
    public function isAnonymous()
    {
        return!$this->isAuthenticated();
    }

    /**
     * Signs in the user on the application.
     *
     * @param DpUser $user The DpUser id
     * @param boolean $reMember Whether or not to reMember the user
     * @param Doctrine_Connection $con A Doctrine_Connection object
     */
    public function signIn(GfUser $user, $action = null, $reMember = false, $isFirst = false, $con = null)
    {
        // signin
        $this->setAttribute('user_id', $user->get('id'), 'dpSecurityUser');
        $this->setAuthenticated(true);
        $this->clearCredentials();
        //$this->addCredentials($user->getAllPermissionNames());
        $this->isSuperAdmin = $user->get('is_super_admin');

        // save last login
        GfUserTable::getInstance()->createQuery()
            ->update('GfUser')
            ->where('id = ?', $user->get('id'))
            ->set('last_login', "'" . date('Y-m-d H:i:s') . "'")
            ->execute();

        // log this activity
        $description = $action->getPartial('common/activity_log', array('type' => $isFirst ? 'signup' : 'signin', 'user' => $user));
        $this->dispatcher->notify(new sfEvent($action, 'activity.log', array('description' => $description, 'points' => $isFirst ? 10 : 2, 'user' => $user)));

        // check to see if the user has been assigned a gallery item already
        if (!is_object((ProfileGalleryItemTable::getInstance()->findOneByUserId($user->getId()))))
        {
            $user->_saveUserGalleryItem();
        }
        
        //die("testing...");

        if (!$user->getNotificationToken())
        {
            // set the notification token for this user
            $user->setNotificationToken(gfToolkit::random(25));
            $user->save();
        }

        // fetch the notification settings for this user
        $notificationSetting = $user->getNotificationSetting();
        if (!is_object($notificationSetting))
        {
            // save the notification settings
            $notificationSetting = new NotificationSetting();
            $notificationSetting->setUser($user);
            $notificationSetting->save();
        }



        $this->user = $user;
    }

    /**
     * Signs out the user.
     *
     */
    public function signOut()
    {
        $this->setAttribute('user_id', null, 'dpSecurityUser');
        $this->getAttributeHolder()->removeNamespace('dpSecurityUser');
        $this->user = null;
        $this->clearCredentials();
        $this->setAuthenticated(false);
        $this->isSuperAdmin = false;
    }

    /**
     * Returns the related DpUser.
     *
     * @return DpUser
     */
    public function getUser()
    {
        if (!$this->user && ($id = $this->getAttribute('user_id', null, 'dpSecurityUser')))
        {
            $this->user = GfUserTable::getInstance()->findOneById($id);

            if (!$this->user)
            {
                // the user does not exist anymore in the database
                $this->signOut();

                return null;
            }
        }

        return $this->user;
    }

    /**
     * Returns the related Doctor.
     *
     * @return Doctor
     */
    public function getDoctor()
    {
        if (!$this->doctor && ($id = $this->getAttribute('user_id', null, 'dpSecurityUser')))
        {
            $this->doctor = DoctorTable::getInstance()->findOneByUserId($id);
        }

        return $this->doctor;
    }

    /**
     * Returns the related Admin.
     *
     * @return Admin
     */
    public function getAdmin()
    {
        if (!$this->admin && ($id = $this->getAttribute('user_id', null, 'dpSecurityUser')))
        {
            $this->admin = AdminTable::getInstance()->findOneByUserId($id);
        }

        return $this->admin;
    }

    /**
     * Returns the related Member.
     *
     * @return Member
     */
    public function getMember()
    {
        if (!$this->member && ($id = $this->getAttribute('user_id', null, 'dpSecurityUser')))
        {
            $this->member = MemberTable::getInstance()->findOneByUserId($id);
        }

        return $this->member;
    }

    /**
     * Returns the related DpUser.
     *
     * @return DpUser
     */
    public function getDpUser()
    {
        return $this->getUser();
    }

    public function getUserId()
    {
        if ($user = $this->getUser())
        {
            return $user->get('id');
        }

        return null;
    }

    /**
     * Returns the string representation of the object.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->getUser()->__toString();
    }

    /**
     * Returns the DpUser object's username.
     *
     * @return string
     */
    public function getUsername()
    {
        return $this->getUser()->get('username');
    }

    /**
     * Returns the DpUser object's email.
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->getUser()->get('email');
    }

    /**
     * Returns the DpUser object's type.
     *
     * @return string
     */
    public function getType()
    {
        return $this->getUser()->get('type');
    }

    /**
     * Sets the user's password.
     *
     * @param string $password The password
     * @param Doctrine_Collection $con A Doctrine_Connection object
     */
    public function setPassword($password, $con = null)
    {
        $this->getUser()->setPassword($password);
        $this->getUser()->save($con);
    }

    /**
     * Returns whether or not the given password is valid.
     *
     * @return boolean
     */
    public function checkPassword($password)
    {
        return $this->getUser()->checkPassword($password);
    }

    /**
     * Sets the doctor id.
     *
     * @param string $doctorId
     */
    public function setDoctorId($doctorId)
    {
        if (!$this->hasAttribute('doctor_id'))
        {
            $this->setAttribute('doctor_id', $doctorId);
        }
    }

    /**
     * Returns the doctor id.
     *
     * @param string $default The default doctor id to return
     * @return string $doctorId The doctor id
     */
    public function getDoctorId($default)
    {
        $doctorId = $this->getAttribute('doctor_id', $default);

        return $doctorId;
    }

    /**
     * Sets the current route.
     *
     * @param string $currentRoute
     */
    public function setCurrentRoute($currentRoute)
    {
        $this->setAttribute('current_route', $currentRoute);
    }

    /**
     * Returns the current route.
     *
     * @param string $default The default current route to return
     * @return string $currentRoute The current route
     */
    public function getCurrentRoute($default)
    {
        $currentRoute = $this->getAttribute('current_route', $default);
        return $currentRoute;
    }

    /**
     * Sets the anonymous question details
     *
     * @param string $questionDetails
     */
    public function setQuestionDetails($questionDetails)
    {
        $this->setAttribute('question_details', $questionDetails);
    }

    /**
     * Returns the anonymous question details
     *
     * @param string $default null
     * @return string $questionDetails the anonymous question details
     */
    public function getQuestionDetails($questionDetails = array())
    {
        $questionDetails = $this->getAttribute('question_details', $questionDetails);
        return $questionDetails;
    }

    /**
     * Sets the book now step one form details
     *
     * @param string $bookNowDetails
     */
    public function setBookNowDetails($bookNowDetails)
    {
        $this->setAttribute('book_now_details', $bookNowDetails);
    }

    /**
     * Returns the book now step one form details
     *
     * @param string $default null
     * @return string $bookNowDetails The current route
     */
    public function getBookNowDetails($bookNowDetails)
    {
        $bookNowDetails = $this->getAttribute('book_now_details', $bookNowDetails);
        return $bookNowDetails;
    }

    /**
     * Sets the registration step one
     *
     * @param string $registrationDetails
     */
    public function setRegistrationDetails($registrationDetails)
    {
        $this->setAttribute('registration_details', $registrationDetails);
    }

    /**
     * Returns the registration step one form details
     *
     * @param string $default null
     * @return string $registrationDetails The current route
     */
    public function getRegistrationDetails($registrationDetails)
    {
        $registrationDetails = $this->getAttribute('registration_details', $registrationDetails);
        return $registrationDetails;
    }

    /**
     * Returns true if user has book now details.
     * @return bool
     */
    public function hasAnAppointment()
    {
        return is_array($this->getBookNowDetails(null));
    }

//    public function getFlash($name, $default = null)
//    {
//        //die("testing...");
//        $flash = parent::getFlash($name, $default);
//        $this->getAttributeHolder()->remove($name, null, 'symfony/user/sfUser/flash');
//        return $flash;
//    }
}
